﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using TM.QWeibo.SDK;
using System.IO;
using System.Collections.Generic;

namespace TM.QWeibo.Common
{
    /// <summary>
    /// 授权验证帮助类
    /// </summary>
    public class OauthHelper
    {
        #region 私有属性

        /// <summary>
        /// App Key
        /// </summary>
        public const string AppKey = "";//输入你的AppKey
        /// <summary>
        /// App Secret
        /// </summary>
        public const string AppSecret = "";//输入你的AppSecret

        /// <summary>
        /// Token
        /// </summary>
        private static string OAuthToken { get; set; }

        /// <summary>
        /// TokenSecret
        /// </summary>
        private static string OAuthTokenSecret { get; set; }

        /// <summary>
        /// Token的存储KEY
        /// </summary>
        private const string TokenStoreKey = "OAuthHelper.Flags.Token";

        /// <summary>
        /// TokenSecret的存储KEY
        /// </summary>
        private const string TokenSecretStoreKey = "OAuthHelper.Flags.TokenSecret";

        #endregion

        #region 公共属性

        /// <summary>
        /// 判断是否授权
        /// </summary>
        public static bool IsVerified
        {
            get
            {
                var val = Common.Isolated.Get("OAuthHelper.Flags.isVerified");
                if (val != null)
                {
                    return (bool)val;
                }
                return false;
            }
            set
            {
                Common.Isolated.Set("OAuthHelper.Flags.isVerified", value);
            }
        }


        /// <summary>
        /// 1.0 oauth_token, 根据不同的场合使用不同的值,如request_token或access_token
        /// </summary>
        public static string Token
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(OAuthToken))
                {
                    return OAuthToken;
                }
                var val = Isolated.Get(TokenStoreKey);
                if (val != null)
                {
                    OAuthToken = (string)val;
                    return OAuthToken;
                }
                return string.Empty;
            }
            set
            {
                OAuthToken = value;
                Isolated.Set(TokenStoreKey, value);
            }
        }

        /// <summary>
        /// 1.0 oauth_token_secret, 根据不同的场合使用不同的值,如request_secret或access_secret
        /// </summary>
        public static string TokenSecret
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(OAuthTokenSecret))
                {
                    return OAuthTokenSecret;
                }
                var val = Isolated.Get(TokenSecretStoreKey);
                if (val != null)
                {
                    OAuthTokenSecret = (string)val;
                    return OAuthTokenSecret;
                }
                return string.Empty;
            }
            set
            {
                OAuthTokenSecret = value;
                Isolated.Set(TokenSecretStoreKey, value);
            }
        }

        #endregion

        #region oauth 2.0

        /// <summary>
        /// Oauth 2 key
        /// </summary>

        private const string AccessTokenKey = "TM.QWeibo.Common.OauthHelper.AccessToken";
        private const string ExpiresInKey = "TM.QWeibo.Common.OauthHelper.ExpiresInKey";
        private const string OpenIdKey = "TM.QWeibo.Common.OauthHelper.OpenIdKey";
        private const string OpenKeyKey = "TM.QWeibo.Common.OauthHelper.OpenKeyKey";
        private const string RefreshTokenKey = "TM.QWeibo.Common.OauthHelper.RefreshTokenKey";
        private const string AccessDayKey = "TM.QWeibo.Common.OauthHelper.AccessDayKey";
        public const string DownloadedIdolListStoreKey = "TM.QWeibo.Common.OauthHelper.DownloadedIdolListStoreKey";


        private static string _AccessToken;
        private static long _ExpiresIn;
        private static string _OpenId;
        private static string _OpenKey;
        private static string _RefreshToken;
        private static long _AccessDay;
        /// <summary>
        /// AccessToken
        /// </summary>
        public static string AccessToken
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(_AccessToken))
                {
                    return _AccessToken;
                }
                var val = Common.Isolated.Get(AccessTokenKey);
                if (val != null)
                {
                    _AccessToken = (string)val;
                    return _AccessToken;
                }
                return string.Empty;
            }
            set
            {
                _AccessToken = value;
                Common.Isolated.Set(AccessTokenKey, value);
            }
        }

        /// <summary>
        /// ExpiresIn(秒)
        /// </summary>
        public static long ExpiresIn
        {
            get
            {
                if (_ExpiresIn>0)
                {
                    return _ExpiresIn;
                }
                var val = Common.Isolated.Get(ExpiresInKey);
                if (val != null)
                {
                    _ExpiresIn = (long)val;
                    return _ExpiresIn;
                }
                return 0;
            }
            set
            {
                _ExpiresIn = value;
                Common.Isolated.Set(ExpiresInKey, value);
            }
        }


        /// <summary>
        /// OpenId
        /// </summary>
        public static string OpenId
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(_OpenId))
                {
                    return _OpenId;
                }
                var val = Common.Isolated.Get(OpenIdKey);
                if (val != null)
                {
                    _OpenId = (string)val;
                    return _OpenId;
                }
                return string.Empty;
            }
            set
            {
                _OpenId = value;
                Common.Isolated.Set(OpenIdKey, value);
            }
        }

        /// <summary>
        /// OpenKey
        /// </summary>
        public static string OpenKey
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(_OpenKey))
                {
                    return _OpenKey;
                }
                var val = Common.Isolated.Get(OpenKeyKey);
                if (val != null)
                {
                    _OpenKey = (string)val;
                    return _OpenKey;
                }
                return string.Empty;
            }
            set
            {
                _OpenKey = value;
                Common.Isolated.Set(OpenKeyKey, value);
            }
        }

        /// <summary>
        /// RefreshToken
        /// </summary>
        public static string RefreshToken
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(_RefreshToken))
                {
                    return _RefreshToken;
                }
                var val = Common.Isolated.Get(RefreshTokenKey);
                if (val != null)
                {
                    _RefreshToken = (string)val;
                    return _RefreshToken;
                }
                return string.Empty;
            }
            set
            {
                _RefreshToken = value;
                Common.Isolated.Set(RefreshTokenKey, value);
            }
        }


        /// <summary>
        /// 授权时间戳(毫秒)
        /// </summary>
        public static long AccessedDay
        {
            get
            {
                if (_AccessDay > 0)
                {
                    return _AccessDay;
                }
                var val = Common.Isolated.Get(AccessDayKey);
                if (val != null)
                {
                    _AccessDay = (long)val;
                    return _AccessDay;
                }
                return 0;
            }
            set
            {
                _AccessDay = value;
                Common.Isolated.Set(AccessDayKey, value);
            }
        }

        #endregion

        #region 公共方法
        /// <summary>
        /// 获取OAuth对象
        /// </summary>
        /// <returns></returns>
        public static OAuth OAuth()
        {
            if (!string.IsNullOrWhiteSpace(AppKey) && !string.IsNullOrWhiteSpace(AppSecret))
            {
                var oauth = new OAuth(AppKey, AppSecret) { Token = Token, TokenSecret = TokenSecret };
                return oauth;
            }
            else {
                throw new Exception("AppKey和AppSecret不能为空！");
            }
        }

        /// <summary>
        /// 获取OAuth对象
        /// </summary>
        /// <returns></returns>
        public static OAuth OAuth2(string ipaddress="127.0.0.1")
        {
            if (   !string.IsNullOrWhiteSpace(AppKey) 
                && !string.IsNullOrWhiteSpace(AppSecret)
                && !string.IsNullOrWhiteSpace(Common.OauthHelper.AccessToken)
                && !string.IsNullOrWhiteSpace(Common.OauthHelper.OpenId)
                )
            {
                var oauth = new OAuth(AppKey, Common.OauthHelper.AccessToken, Common.OauthHelper.OpenId, ipaddress);
                return oauth;
            }
            else
            {
                throw new Exception("授权参数不正确！");
            }
        }

        public static void RefreshAccessTokenForOauth2(Action callback=null){
            if (string.IsNullOrWhiteSpace(OauthHelper.AppKey) || string.IsNullOrWhiteSpace(OauthHelper.RefreshToken)) {
                return;
            }
            var uri = new Uri(string.Format("https://open.t.qq.com/cgi-bin/oauth2/access_token?client_id={0}&grant_type=refresh_token&refresh_token={1}", OauthHelper.AppKey, OauthHelper.RefreshToken), UriKind.Absolute);
            var rq = (HttpWebRequest)WebRequest.Create(uri);
            rq.AllowReadStreamBuffering = false;
            rq.Method = "GET";
            rq.BeginGetResponse((asynchronousResult)=>{
                var request = (HttpWebRequest)asynchronousResult.AsyncState;
                var response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                var streamResponse = response.GetResponseStream();
                var streamRead = new StreamReader(streamResponse);
                var responseString = streamRead.ReadToEnd();
                streamResponse.Close();
                streamRead.Close();
                response.Close();
                UpdateAcceckToken(responseString);
                if (callback != null) {
                    callback();
                }
            },rq);
            
        }
        /// <summary>
        /// 授权是否过期
        /// </summary>
        /// <returns></returns>
        public static bool IsAccessTokenExpired() {
            var now = Timestamp(DateTime.Now);
            var rs= (now-AccessedDay)>(ExpiresIn*1000-24*60*60);
            return rs;
        }

        private static void UpdateAcceckToken(string str) {
            var rs = new Dictionary<string,string>();
            var tmpKeyVals = str.Split('&');
            for (int i = 0; i < tmpKeyVals.Length; i++)
            {
                var kv = tmpKeyVals[i].Split('=');
                if (kv.Length > 1)
                {
                    rs.Add(kv[0], kv[1]);
                }
            }
            if (
                rs.ContainsKey("access_token")
                && rs.ContainsKey("expires_in")
                && rs.ContainsKey("refresh_token") 
                ) {
                    OauthHelper.AccessToken = rs["access_token"];
                    OauthHelper.ExpiresIn = long.Parse(rs["expires_in"]);
                    OauthHelper.RefreshToken = rs["refresh_token"];
                    OauthHelper.AccessedDay = Timestamp(DateTime.Now);
            }
        }

        /// <summary>
        /// 注销帐号
        /// </summary>
        public static void Logout()
        {
            Token = string.Empty;
            TokenSecret = string.Empty;
            RefreshToken = string.Empty;
            AccessToken = string.Empty;
            OpenId = string.Empty;
            OpenKey = string.Empty;
            ExpiresIn = 0;
            AccessedDay = 0;
            Isolated.Remove(DownloadedIdolListStoreKey);
        }

        #endregion
        private static DateTime UnixTimestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        //时间戳
        public static long Timestamp(DateTime date) {
            return (long)(date.ToUniversalTime() - UnixTimestamp).TotalMilliseconds;
        }
    }
}
